package com.yh.mybatis.extention.plugin.comment;

import org.mybatis.generator.api.*;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.api.dom.xml.XmlElement;
import org.mybatis.generator.config.PropertyRegistry;
import org.mybatis.generator.internal.DefaultCommentGenerator;
import org.mybatis.generator.internal.util.StringUtility;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;

/**
 * @author liubing
 * 自定义字段注解生成器
 * @date 2019-04-28
 */
public class YhCommentGenerator  extends DefaultCommentGenerator {

    /**
     * 自定义属性集合
     */
    private Properties customProperties;

    /**
     * 系统属性集合
     */
    private Properties systemProperties;

    /**
     * 是否打开时间标准
     * true: 打开
     * false: 关闭
     */
    private boolean suppressDate;

    /**
     * 是否开启字段注解
     * true: 打开
     * false: 关闭
     */
    private boolean suppressAllComments;

    /**
     * 当前时间
     * 字符类型
     */
    private String currentDate;

    private static final String DAY_FORMAT = "yyyy-MM-dd";

    public YhCommentGenerator() {
        super();
        customProperties = new Properties();
        systemProperties = System.getProperties();
        suppressDate = Boolean.TRUE;
        suppressAllComments = Boolean.TRUE;
        currentDate = (new SimpleDateFormat(DAY_FORMAT)).format(new Date());
    }

    @Override
    public void addConfigurationProperties(Properties properties) {
        this.customProperties.putAll(properties);
        suppressDate = StringUtility.isTrue(properties.getProperty(PropertyRegistry.COMMENT_GENERATOR_SUPPRESS_DATE));
        suppressAllComments = StringUtility.isTrue(properties.getProperty(
                PropertyRegistry.COMMENT_GENERATOR_SUPPRESS_ALL_COMMENTS));
    }

    @Override
    public void addFieldComment(Field field, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {
        if (Boolean.FALSE.equals(suppressAllComments)) {
            return;
        }
        StringBuilder fieldStringBuilder = new StringBuilder();
        field.addJavaDocLine("/**");
        fieldStringBuilder.append(" * ");
        fieldStringBuilder.append(introspectedColumn.getRemarks());
        field.addJavaDocLine(fieldStringBuilder.toString());
        field.addJavaDocLine(" */");
        return;
    }

    @Override
    public void addFieldComment(Field field, IntrospectedTable introspectedTable) {
        if (Boolean.FALSE.equals(suppressAllComments)) {
            return;
        }

        StringBuilder fieldStringBuilder = new StringBuilder();
        fieldStringBuilder.append(" * ");
        fieldStringBuilder.append(introspectedTable.getFullyQualifiedTable());

        field.addJavaDocLine("/**");
        field.addJavaDocLine(fieldStringBuilder.toString());
        //字段注解
        field.addJavaDocLine(" */");
    }

    @Override
    public void addModelClassComment(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        FullyQualifiedTable table = introspectedTable.getFullyQualifiedTable();
        topLevelClass.addJavaDocLine("/**");
        topLevelClass.addJavaDocLine(" * " + table.toString() + "<p/>");
        topLevelClass.addJavaDocLine(" * @date " + new Date().toString());
        topLevelClass.addJavaDocLine(" * @author jingshao" );
        topLevelClass.addJavaDocLine(" *");
        topLevelClass.addJavaDocLine(" */");
    }

    @Override
    public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable) {
        this.addClassComment(innerClass,introspectedTable,suppressAllComments);
    }

    @Override
    public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable, boolean b) {
        if(Boolean.FALSE.equals(b)){
            return ;
        }
        StringBuilder sb = new StringBuilder();
        innerClass.addJavaDocLine("/**");
        sb.append(" * ");
        sb.append(introspectedTable.getFullyQualifiedTable());
        sb.append(" ");
        sb.append(getDateString());
        innerClass.addJavaDocLine(sb.toString());
        innerClass.addJavaDocLine(" */");
    }

    @Override
    public void addEnumComment(InnerEnum innerEnum, IntrospectedTable introspectedTable) {
        if (Boolean.FALSE.equals(suppressAllComments)) {
            return;
        }

        StringBuilder enumStringBuilder = new StringBuilder();

        innerEnum.addJavaDocLine("/**");
        enumStringBuilder.append(" * ");
        enumStringBuilder.append(introspectedTable.getFullyQualifiedTable());
        innerEnum.addJavaDocLine(enumStringBuilder.toString());
        innerEnum.addJavaDocLine(" */");
    }

    @Override
    public void addGetterComment(Method method, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {
        if (Boolean.FALSE.equals(suppressAllComments)) {
            return;
        }
        method.addJavaDocLine("/**");
        StringBuilder getterStringBuilder = new StringBuilder();
        getterStringBuilder.append(" * ");
        getterStringBuilder.append(introspectedColumn.getRemarks());
        method.addJavaDocLine(getterStringBuilder.toString());
        getterStringBuilder.setLength(0);
        getterStringBuilder.append(" * @return ");
        getterStringBuilder.append(introspectedColumn.getActualColumnName());
        getterStringBuilder.append(" ");
        getterStringBuilder.append(introspectedColumn.getRemarks());
        method.addJavaDocLine(getterStringBuilder.toString());
        method.addJavaDocLine(" */");
    }

    @Override
    public void addSetterComment(Method method, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {
        if (Boolean.FALSE.equals(suppressAllComments)) {
            return;
        }
        method.addJavaDocLine("/**");
        StringBuilder setterStringBuilder = new StringBuilder();
        setterStringBuilder.append(" * ");
        setterStringBuilder.append(introspectedColumn.getRemarks());
        method.addJavaDocLine(setterStringBuilder.toString());

        Parameter parm = method.getParameters().get(0);
        setterStringBuilder.setLength(0);
        setterStringBuilder.append(" * @param ");
        setterStringBuilder.append(parm.getName());
        setterStringBuilder.append(" ");
        setterStringBuilder.append(introspectedColumn.getRemarks());
        method.addJavaDocLine(setterStringBuilder.toString());
        method.addJavaDocLine(" */");
    }

    @Override
    public void addGeneralMethodComment(Method method, IntrospectedTable introspectedTable) {
        // add no document level comments by default
        return ;
    }

    @Override
    public void addJavaFileComment(CompilationUnit compilationUnit) {
        // add no document level comments by default
        return;
    }

    @Override
    public void addComment(XmlElement xmlElement) {
        //Adds a suitable comment to warn users that the element was generated, and when it was generated.
        return;
    }

    @Override
    public void addRootComment(XmlElement xmlElement) {
        // add no document level comments by default
        return;
    }
    @Override
    protected String getDateString() {
        String result = null;
        if (!suppressDate) {
            result = currentDate;
        }
        return result;
    }

    @Override
    protected void addJavadocTag(JavaElement javaElement, boolean markAsDoNotDelete) {
        StringBuilder sb = new StringBuilder();
        sb.append(" * ");
        sb.append("@date");
        String s = getDateString();
        if (s != null) {
            sb.append(' ');
            sb.append(s);
        }
        javaElement.addJavaDocLine(sb.toString());
    }
}
